﻿using FluentEmail.Core;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using Mapster.Utils;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Nest;
using NewLife.Model;
using Newtonsoft.Json;
using OBS.Model;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using OfficeOpenXml.FormulaParsing.Utilities;
using Org.BouncyCastle.Ocsp;
using PuppeteerSharp;
using QRCoder;
using RabbitMQ.Client;
using EMC.VISITOR.Core;
using SapNwRfc;
using SapNwRfc.Pooling;
using SQLitePCL;
using SqlSugar;
using SqlSugar.DistributedSystem.Snowflake;
using SqlSugar.Extensions;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Dynamic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml.Linq;
using Yitter.IdGenerator;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinAccountGetAccountBasicInfoResponse.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinExpressBusinessAccountGetAllResponse.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinGetCurrentSelfMenuInfoResponse.Types.Menu.Types.Button.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.ComponentTCBBatchCreateContainerServiceVersionRequest.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.WxaBusinessGetUserEncryptKeyResponse.Types;
using static SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.AddHKSubMerchantRequest.Types;
using static System.Net.Mime.MediaTypeNames;
using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinDraftBatchGetResponse.Types.Item.Types;
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using static SKIT.FlurlHttpClient.Wechat.Api.Events.XPayGoodsDeliverNotifyEvent.Types;

namespace EMC.VISITOR.Application;
/// <summary>
/// 单位信息服务
/// </summary>
[ApiDescriptionSettings(MyBusConst.GroupName, Order = 100)]
public partial class CommonService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<SysUser> _repUser;
    private readonly SqlSugarRepository<SysPrint> _printRep;
    private readonly SysFileService _sysFileService;
    private readonly SysUserService _sysUserService;
    public CommonService(
        SqlSugarRepository<SysPrint> printRep,
       SqlSugarRepository<SysUser> repUser,
       SysFileService sysFileService,
       SysUserService sysUserService)
    {
        _repUser = repUser;
        _printRep = printRep;
        _sysFileService = sysFileService;
        _sysUserService = sysUserService;
    }
    [AllowAnonymous]
    [HttpPost]
    public bool CheckSystemKey([FromBody] string key)
    {
        return true;
    }
    [AllowAnonymous]
    [HttpPost]
    public async Task<JRResult<string>> FeedbackAdd([FromBody] SysFeedback input)
    {
        if (input == null)
            return CustomeResult.Fail();
        if (!input.Type.HasValue)
            return CustomeResult.Fail<string>("请选择反馈类型！");
        if (input.Description.IsNullOrEmptyOrNullString())
            return CustomeResult.Fail<string>("请录入反馈内容！");

        await _repUser.Context.MyInsertable<SysFeedback>(input).ExecuteCommandAsync();
        return CustomeResult.Success();
    }


    [AllowAnonymous]
    [HttpPost]
    public async Task<dynamic> App_version(SysAppVersion version)
    {
        /* res的数据说明
                * | 参数名称        | 一定返回     | 类型        | 描述
                * | -------------|--------- | --------- | ------------- |
                * | versionCode     | y        | int       | 版本号        |
                * | versionName     | y        | String    | 版本名称      |
                * | versionInfo     | y        | String    | 版本信息      |
                * | updateType      | y        | String    | forcibly = 强制更新, solicit = 弹窗确认更新, silent = 静默更新 |
                * | downloadUrl     | y        | String    | 版本下载链接（IOS安装包更新请放跳转store应用商店链接,安卓apk和wgt文件放文件下载链接）  |
                */
        var dbVersion = await _repUser.Context.Queryable<SysAppVersion>().OrderByDescending(r => r.CreateTime).FirstAsync();
        //前端传过来的版本号与后端的版本号一致说明不需要更新
        if (dbVersion == null || dbVersion.VersionName.IsNullOrEmpty() || dbVersion.VersionName.Trim().Equals(version.VersionName))
        {
            return null;
        }
        var data = new
        {
            VersionCode = dbVersion.VersionCode,
            VersionName = dbVersion.VersionName,
            VersionInfo = $"当前版本:{version.VersionName},更新后版本:{dbVersion.VersionName}\r\n {dbVersion.VersionInfo}",
            DownloadUrl = dbVersion.DownloadUrl,
            UpdateType = dbVersion.UpdateType.ToString()
        };
        return data;
    }

    [AllowAnonymous]
    [HttpGet]
    public async Task<dynamic> GetUserInfos()
    {
        var userList = await _repUser.GetListAsync();
        return userList.Select(r =>
         new
         {
             id = r.Id,
             key = r.Account,
             label = r.RealName,

             value = new KeyValue
             {
                 id = r.Id,
                 label = r.RealName,
                 key = r.Account,
                 value = r.Id
             }
         }).ToList();
    }




    /// <summary>
    /// 获取打印模版
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet]
    public async Task<SysPrint> GetPrintTemplate(string templateName)
    {
        var print = await _printRep.AsQueryable().Where(r => r.Name == templateName).FirstAsync();
        return print;
    }

    /// <summary>
    /// 打印
    /// </summary>
    /// <param name="orderIds">表id集合</param>
    /// <param name="printTemplateName">打印模版名称</param>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpPost]
    public async Task<JRResult<dynamic>> PrintDataLoad(List<long> ids, string printTemplateName)
    {
        switch (printTemplateName)
        {
            case "工程監工日誌V1":
            case "工程監工日誌V2":
            case "工程監工日誌V3":
            case "工程監工日誌V4":
                return await PrintLogisticsTracking(ids);
                break;

            //case "订单打印V2":
            //    return await PrintWorkOrder(ids);
            //    break;
            //case "生产订单":
            //    return await PrintSAPWorkOrder(ids);
            //    break;
            //case "生产订单V2":
            //    return await PrintSAPWorkOrder(ids);
            //    break;
            //case "生产订单V3":
            //    return await PrintSAPWorkOrderV3(ids);
            //    break;
            //case "生产订单V4":
            //    return await PrintSAPWorkOrderV3(ids);
            //    break;
            //case "工位编码打印":
            //    return await StationPrint(ids);
            //    break;
            //case "报工人员打印":
            //    return await ReportUserPrint(ids);
            //    break;
            //case "系统用户打印":
            //    return await ReportSysUserPrint(ids);
            //    break;
            default:
                break;
        }
        return default(JRResult<dynamic>);
    }

    /// <summary>
    /// 工程監工日誌V1 -
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    private async Task<JRResult<dynamic>> PrintLogisticsTracking(List<long> ids)
    {
        if (ids == null || ids.Count <= 0)
        {
            return CustomeResult.Fail<dynamic>();
        }
        DateTime time = DateTime.Now;
        List<dynamic> response = new List<dynamic>();
        var _db = _repUser.Context;
        int pageSize = 4; // 每次打印 4 个 用户
        var sgjks = await _db.MyQueryable<FlowSystemSGJK>().Where(r => ids.Contains(r.Id)).ToListAsync();

        foreach (var item in sgjks)
        {
            var supperName = ChineseConverter.Convert(item.supplier_name, ChineseConversionDirection.TraditionalToSimplified);//转简体
            var projectName = ChineseConverter.Convert(item.project_name, ChineseConversionDirection.TraditionalToSimplified);//转简体
            int visitiorCount = 0;

            if (!item.EnterTime.HasValue)
            {
                var visLogs = await _db.MyQueryable<VisitLog>().Where(r => (r.WaitToEnterTime >= time.Date && r.WaitToEnterTime < time.Date.AddDays(1)) &&
                 r.Type == VisitorType.Build && r.Status >= ProcessStatus.WaitToEnter && r.Vcompany == supperName).ToListAsync();
                var logs = visLogs.Where(r => r.Vreason.Contains(projectName)).Distinct(r => r.Visitor).ToList();
                visitiorCount = logs.Count;
            }
            else
            {
                time = item.EnterTime.Value.Date;
                //查询历史
                var visLogs = await _db.MyQueryable<VisitLog_History>().Where(r => (r.WaitToEnterTime >= time && r.WaitToEnterTime < time.AddDays(1))
                   && r.Type == VisitorType.Build && r.Status >= ProcessStatus.WaitToEnter && r.Vcompany == supperName
                   ).ToListAsync();
                var logs = visLogs.Where(r => r.Vreason.Contains(projectName)).Distinct(r => r.Visitor).ToList();
                visitiorCount = logs.Count;
            }

            string logoImage = string.Empty, imageUrl0 = string.Empty, imageUrl1 = string.Empty, imageUrl2 = string.Empty, imageUrl3 = string.Empty;
            if (!item.Images.IsNullOrEmpty())
            {
                var images = JsonConvert.DeserializeObject<List<DocImgModel>>(item.Images);
                for (int i = 0; i < images.Count; i++)
                {
                    if (i == 0)
                        imageUrl0 = DownImageToBase64String(images[i].url);
                    else if (i == 1)
                        imageUrl1 = DownImageToBase64String(images[i].url);
                    else if (i == 2)
                        imageUrl2 = DownImageToBase64String(images[i].url);
                    else if (i == 3)
                        imageUrl3 = DownImageToBase64String(images[i].url);
                }
            }
            var setting = await CommonUtil.GetConfigValue("PrintLogoUrl");
            if (!setting.IsNullOrEmpty())
                logoImage = DownImageToBase64String(setting);

            response.Add(new
            {
                date = time.ToString("yyyy-MM-dd"),
                supper_name = item.supplier_name,
                project_name = item.project_name,
                personCount = visitiorCount.ToString(),
                content = item.Content,
                progress = item.Progress,
                changeProject = item.ChangeProject,
                logoImage = logoImage,
                imageUrl0 = imageUrl0,
                imageUrl1 = imageUrl1,
                imageUrl2 = imageUrl2,
                imageUrl3 = imageUrl3
            });
        }
        return CustomeResult.Success<dynamic>("加载打印画面中，请稍等......", response);
    }


    class DocImgModel
    {
        public string name { get; set; }
        public string url { get; set; }

        public DateTime? time { get; set; }
    }

    private bool remoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
    {
        return true;
    }
    private string DownImageToBase64String(string imageUrl)
    {
        return "data:image/png;base64," + HttpUtil.HttpGetBase64String(imageUrl, null);
    }

    [AllowAnonymous]
    [HttpPost]
    public virtual async Task<JsonResult> OptionConfig([FromBody] string configPath)
    {



        if (configPath.IsNullOrEmpty())
            return null;

        configPath = configPath.Trim().ToLower();
        var option = await _repUser.Context.Queryable<SysPageOptionConfig>()
            .Includes(r => r.column).FirstAsync(r => r.configPath.ToLower() == configPath);

        var optionView = option.Adapt<SysPageOptionConfigView>();
        if (optionView != null)
            optionView.column = optionView.column.Where(r => r.IsDelete == false).OrderBy(r => r.hide).OrderByDescending(r => r.order).ToList();
        else
            optionView = new SysPageOptionConfigView();
        return new JsonResult(optionView, new JsonSerializerSettings()
        {
            NullValueHandling = NullValueHandling.Ignore
        });


    }

    [AllowAnonymous]
    [HttpPost]
    [UnitOfWork(true)]
    public virtual async Task FlowCreate([FromBody] SysAuditFlowTemplate template)
    {
        var db = _repUser.Context;
        decimal maxVersion = 1.0m;
        var maxTemplate = await db.MyQueryable<SysAuditFlowTemplate>().Where(r =>
           r.Name == template.Name &&
           r.GroupName == template.GroupName &&
           r.Status == true).OrderByDescending(r => r.Version).FirstAsync();
        if (maxTemplate != null)
        {
            maxTemplate.Status = false; //最大的版本的模版禁用
            maxVersion = maxTemplate.Version;
        }

        var model = SysAuditFlowTemplate.CreateFlowTemplate("");
        model.tableId = YitIdHelper.NextId();
        model.workFlowDef.name = template.Name;

        template.Content = model.ToJson();
        template.Version = maxVersion <= 0 ? 1.0m : maxVersion + 0.1m;
        template.Status = true; //启用最新的模版

        await db.MyInsertable<SysAuditFlowTemplate>(template).ExecuteCommandAsync();
        await db.MyUpdateable<SysAuditFlowTemplate>(maxTemplate).ExecuteCommandAsync();
    }





    #region 数据复制
    /// <summary>
    /// 复制Avue字段信息
    /// </summary>
    /// <param name="oldConfigPath">需要被复制的页面路径</param>
    /// <param name="newConfigPath">新页面路径</param>
    /// <param name="newConfigCode">新页面代码</param>
    /// <param name="newConfigName">新页面名称</param>

    /// <returns></returns>
    [HttpGet]
    public async Task<JRResult<string>> CopyAvueSettings([FromQuery] string oldConfigPath,
        [FromQuery] string newConfigPath,
        [FromQuery] string newConfigCode,
        [FromQuery] string newConfigName)
    {
        if (oldConfigPath.IsNullOrEmpty() ||
            newConfigPath.IsNullOrEmpty() ||
            newConfigCode.IsNullOrEmpty() ||
            newConfigName.IsNullOrEmpty())
        {
            return CustomeResult.Fail($"有字段为空！");
        }

        var config = await _repUser.Context.MyQueryable<SysPageOptionConfig>()
            .Includes(r => r.column)
            .FirstAsync(r => r.configPath.ToLower() == oldConfigPath.Trim().ToLower());
        if (config == null)
            return CustomeResult.Fail($"未找到：{oldConfigPath}的配置！");

        var newConfig = await _repUser.Context.MyQueryable<SysPageOptionConfig>().FirstAsync(r => r.configPath.ToLower() == newConfigPath.Trim().ToLower());
        if (newConfig != null)
            return CustomeResult.Fail($"系统已存在相同路径：{newConfigPath}的配置，无需重复配置！");

        config.Id = YitIdHelper.NextId();
        config.configPath = newConfigPath;
        config.configCode = newConfigCode;
        config.configName = newConfigName;
        config.CreateTime = DateTime.Now;
        config.UpdateTime = DateTime.Now;
        config.column.ForEach(c =>
        {
            c.Id = YitIdHelper.NextId();
            c.configPath = newConfigPath;
            c.CreateTime = DateTime.Now;
            c.UpdateTime = DateTime.Now;
        });
        await _repUser.Context.MyInsertable<SysPageOptionConfig>(config).ExecuteCommandAsync();
        if (config.column.Count > 0)
            await _repUser.Context.MyInsertable<SysPageOptionConfigColumn>(config.column).ExecuteCommandAsync();

        return CustomeResult.Success("复制成功！");
    }

    #endregion

    /// <summary>
    /// 快速创建用户
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public async Task<string> FastCreateUsers(List<string> accountList)
    {
        var _db = _repUser.Context;
        var pos = await _db.MyQueryable<SysPos>().FirstAsync(r => r.Code == "qt");
        var org = await _db.MyQueryable<SysOrg>().FirstAsync(r => r.Pid == 0);
        var role = await _db.MyQueryable<SysRole>().FirstAsync(r => r.Name == "系统管理员");
        foreach (var user in accountList)
        {
            await _sysUserService.AddUser(new AddUserInput
            {
                Account = user,
                RealName = user,
                NickName = user,
                JobNum = user,
                Phone = "13100000000",
                AccountType = AccountTypeEnum.NormalUser,
                Birthday = DateTime.Now,
                CardType = CardTypeEnum.IdCard,
                OrgId = org != null ? org.Id : 0,
                PosId = pos != null ? pos.Id : 0,
                RoleIdList = role != null ? new List<long> { role.Id } : new List<long> { 0 }
            });
        }
        return "创建成功！";
    }
}

